import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

class DragBackWidget extends StatefulWidget {
  @override
  _DragBackWidgetState createState() => _DragBackWidgetState();
}

class _DragBackWidgetState extends State<DragBackWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Align(
            alignment: Alignment.center,
            child: DragContainer(),
          )
        ],
      ),
    );
  }
}

class DragContainer extends StatefulWidget {
  @override
  _DragContainerState createState() => _DragContainerState();
}

class _DragContainerState extends State<DragContainer>
    with TickerProviderStateMixin {
  late AnimationController animalController;
  late Animation<double> animation;

  double offsetDistance = 0.0;

  ///滑动位置超过这个位置，会滚到顶部；小于，会滚动底部。
  // double maxOffsetDistance;
  // bool onResetControllerValue = false;

  @override
  void initState() {
    animalController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 300));

    // ///easeOut 先快后慢
    // final CurvedAnimation curve =
    //     new CurvedAnimation(parent: animalController, curve: Curves.easeOut);
    // animation = Tween(begin: start, end: end).animate(curve)
    //   ..addListener(() {
    //     offsetDistance = animation.value;
    //     setState(() {});
    //   });

    // ///自己滚动
    // animalController.forward();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    double scale = 1.0;
    if (offsetDistance > 0) {
      MediaQueryData mediaQuery = MediaQuery.of(context);
      var screenHeight = mediaQuery.size.height / 2;
      scale = (screenHeight - offsetDistance) / screenHeight;
    }

    ///使用Transform.translate 移动drag的位置
    return Transform.scale(
      scale: scale,
      child: Transform.translate(
        offset: Offset(0.0, offsetDistance),
        child: RawGestureDetector(
          gestures: {MyVerticalDragGestureRecognizer: getRecognizer()},
          child: Container(
            width: 300.0,
            height: 500.0,
            color: Colors.brown,
          ),
        ),
      ),
    );
  }

  GestureRecognizerFactoryWithHandlers<MyVerticalDragGestureRecognizer>
      getRecognizer() {
    return GestureRecognizerFactoryWithHandlers(
        () => MyVerticalDragGestureRecognizer(), this._initializer);
  }

  void _initializer(MyVerticalDragGestureRecognizer instance) {
    instance
      ..onStart = _onStart
      ..onUpdate = _onUpdate
      ..onEnd = _onEnd;
  }

  ///接受触摸事件
  void _onStart(DragStartDetails details) {
    print('触摸屏幕${details.globalPosition}');
  }

  ///垂直移动
  void _onUpdate(DragUpdateDetails details) {
    print('垂直移动${details.delta}');
    offsetDistance = offsetDistance + details.delta.dy;
    print("拖拽后的offset:$offsetDistance");
    setState(() {});
  }

  ///手指离开屏幕
  void _onEnd(DragEndDetails details) {
    // print('离开屏幕${details.velocity}');
    print("离开屏幕$offsetDistance");

    ///很重要！！！动画完毕后，controller.value = 1.0， 这里要将value的值重置为0.0，才会再次运行动画
    ///重置value的值时，会刷新UI，故这里使用[onResetControllerValue]来进行过滤。
    // animalController.value = 0.0;
    double start;
    double end;
    if (offsetDistance <= 1000) {
      ///这个判断通过，说明已经child位置超过警戒线了，需要滚动到顶部了
      start = offsetDistance;
      end = 0.0;
    } else {
      start = offsetDistance;
      end = 0.0;
      // end = defaultOffsetDistance;
    }

    // easeOut 先快后慢
    final CurvedAnimation curve = CurvedAnimation(
      parent: animalController,
      curve: Curves.easeOut,
    );
    animation = Tween(
      begin: start,
      end: end,
    ).animate(curve)
      ..addListener(() {
        offsetDistance = animation.value;
        setState(() {});
      });
    // 自己滚动
    animalController.forward(from: 0);
  }
}

class MyVerticalDragGestureRecognizer extends VerticalDragGestureRecognizer {
  MyVerticalDragGestureRecognizer({Object? debugOwner})
      : super(debugOwner: debugOwner);
}
